package org.dev.hi.hiui.cityselector

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.text.TextUtils
import android.util.AttributeSet
import android.util.SparseArray
import android.view.*
import android.widget.CheckedTextView
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import kotlinx.android.synthetic.main.dialog_city_selector.*
import org.dev.hi.hiui.R
import org.dev.hi.hiui.item.HiViewHolder
import org.dev.hi.hiui.tab.top.HiTabTopInfo
import org.dev.hi.library.util.HiDisPlayUtils
import org.dev.hi.library.util.HiRes
import java.lang.IllegalStateException

/**
 * Author WenPing
 * CreateTime 2021/9/5.
 * Description:
 */
class CitySelectorDialogFragment : AppCompatDialogFragment() {

    private var citySelectListener: onCitySelectListener? = null

    //用来记录我们本次，或者是之前它已经选择一次了，又传递了进啦
    //包含已选择省，市，区
    private lateinit var province: Province
    private var dataSets: List<Province>? = null
    private val defaultColor = HiRes.getColor(R.color.color_333)
    private val selectColor = HiRes.getColor(R.color.color_dd2)
    private val pleasePickStr = HiRes.getString(R.string.city_selector_tab_hint)

    private val topTabs = mutableListOf<HiTabTopInfo<Int>>()

    //tabLayout 的选中项
    private var topTabSelectIndex = 0

    companion object {
        private const val KEY_PARAMS_DATA_SET = "key_data_set"
        private const val KEY_PARAMS_DATA_SELECT = "key_data_select"

        private const val TAB_PROVINCE = 0
        private const val TAB_CITY = 1
        private const val TAB_DISTRICT = 2

        /**
         * 创建实例
         */
        fun newInstance(province: Province?, list: List<Province>): CitySelectorDialogFragment {
            val args = Bundle()
            args.putParcelable(KEY_PARAMS_DATA_SELECT, province)
            args.putParcelableArrayList(KEY_PARAMS_DATA_SET, ArrayList(list))
            val fragment = CitySelectorDialogFragment()
            fragment.arguments = args
            return fragment
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val window = dialog?.window
        // 直接使用content作为父布局;如果window为空container
        val contentView =
            inflater.inflate(
                R.layout.dialog_city_selector, window?.findViewById(android.R.id.content)
                    ?: container, false
            )
        window?.apply {
            setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            setLayout(
                WindowManager.LayoutParams.MATCH_PARENT,
                (HiDisPlayUtils.getDisplayHeightInPx(inflater.context) * 0.6f).toInt()
            )
        }
        // xia
        window?.setGravity(Gravity.BOTTOM)
        return contentView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        close.setOnClickListener { dismiss() }

        // 获得province等数据
        this.province = arguments?.getParcelable(KEY_PARAMS_DATA_SELECT) ?: Province()
        this.dataSets = arguments?.getParcelableArrayList(KEY_PARAMS_DATA_SET)
        // 加非空判断
        requireNotNull(dataSets) { "params dataSet cannot be null" }

        refreshTabLayoutCount()
        tab_layout.addTabSelectedChangeListener { index, prevInfo, nextInfo ->
            // tabLayout 选中第二个,viewpager可能还在第一个,通过同步viewpager的页面选中项
            if (view_pager.currentItem != index) {
                view_pager.setCurrentItem(index)
            }
        }
        view_pager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
            override fun onPageSelected(position: Int) {
                if (position != topTabSelectIndex) {
                    // 去通知toptabLayout 进行标签的切换
                    tab_layout.defaultSelected(topTabs[position])
                    topTabSelectIndex = position
                }
            }
        })

        // 创建 CityPagerAdapter
        view_pager.adapter = CityPagerAdapter { tabIndex, selectDistrict ->
            // tabIndex 表示那个列表发生了点击事件
            // selectDistrict 代表该页面选中的数据对象[省市区]
            when (selectDistrict.type) {
                TYPE_PROVINCE -> {
                    province = selectDistrict as Province
                }
                TYPE_CITY -> {
                    province.selectCity = selectDistrict as City
                }
                TYPE_DISTRICT -> {
                    province.selectDistrict = selectDistrict
                }
            }
            // 如果说本次选中的数据对象的type不是区的类型
            if (!TextUtils.equals(selectDistrict.type, TYPE_DISTRICT)) {
                refreshTabLayoutCount()
            } else {
                citySelectListener?.onCitySelect(province)
                dismiss()
            }
        }
    }

    private fun refreshTabLayoutCount() {
        topTabs.clear()
        // 添加一个请选择的 tab标签
        var addPleasePickTab = true
        // 构建省tab
        if (!TextUtils.isEmpty(province.id)) {
            topTabs.add(newTabTopInfo(province.districtName))
        }
        // 构建市tab
        if (province.selectCity != null) {
            topTabs.add(newTabTopInfo(province.selectCity!!.districtName))
        }
        // 构建区tab
        if (province.selectDistrict != null) {
            topTabs.add(newTabTopInfo(province.selectDistrict!!.districtName))
            addPleasePickTab = false
        }

        if (addPleasePickTab) {
            topTabs.add(newTabTopInfo(pleasePickStr))
        }
        // 刷新数据
        view_pager.adapter?.notifyDataSetChanged()

        //notifyDataSetChanged它是异步
        // inflateInfo，defaultSelected是同步，就会触发addTabSelectedChangeListener，进而触发viewpager.setCurrenItem
        // 如果viewpager 还没刷新完成， 还没有从1页变成2页，此时肯定会报错
        tab_layout.post {
            tab_layout.inflateInfo(topTabs as List<HiTabTopInfo<*>>)
            //场景是 addPleasePickTab =true ,省市区还没选择完，此时需要选择最后一个tab
            // addPleasePickTab=false.,省市区都已经选择完了，就发生在第二次进入
            tab_layout.defaultSelected(topTabs[if (addPleasePickTab) topTabs.size - 1 else 0])
        }
    }

    private fun newTabTopInfo(districtName: String?) =
        HiTabTopInfo(districtName, defaultColor, selectColor)


    fun setCitySelectListener(listener: onCitySelectListener) {
        this.citySelectListener = listener
    }

    interface onCitySelectListener {
        fun onCitySelect(province: Province)
    }

    /**
     * 创建 CityPagerAdapter
     * 继承自pagerAdapter
     */
    inner class CityPagerAdapter(private val itemClickCallback: (Int, District) -> Unit) :
        PagerAdapter() {

        // 带有3个列表控件的集合
        private val views = SparseArray<CityListView>(3)

        override fun instantiateItem(container: ViewGroup, position: Int): Any {
            // 1.需要完成对应页面的view的创建;如果没获取到就创建
            val view = views.get(position) ?: CityListView(container.context)
            // 2.把页面的position和view绑定关系存储
            views.put(position, view)
            // 3.找出每一个页面position = 0[省份]的选中项
            var select: District? = null
            val list = when (position) {
                TAB_PROVINCE -> {
                    select = province // 如果还未选择过,自然是没有,如果选择过了province,就不为空,就是当前页选中项
                    dataSets
                }
                TAB_CITY -> {
                    select = province.selectCity
                    province.cities
                }
                TAB_DISTRICT -> {
                    select = province.selectDistrict
                    province.selectCity!!.districts
                }
                else -> throw IllegalStateException("pageCount must be less than ${views.size()}")
            }
            // 传入接口回调实例;view 是当前的cityListView
            view.setData(select, list) { selectDistrict ->
                if (view_pager.currentItem != position) return@setData
                itemClickCallback(position, selectDistrict)
            }
            if (view.parent == null) container.addView(view)
            return view
        }

        override fun getItemPosition(`object`: Any): Int {
            // 需要根据object,instantiateItem 返回的值就是 CityListView;判断它是第几个页面
            return if (views.indexOfValue(`object` as CityListView) > 0) POSITION_NONE else POSITION_UNCHANGED

        }

        override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
            // 移除对应的控件
            container.removeView(views[position])
        }

        override fun getCount(): Int = topTabs.size

        override fun isViewFromObject(view: View, `object`: Any): Boolean = view == `object`
    }

    // 创建recyclerView的派生类
    inner class CityListView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyle: Int = 0
    ) : RecyclerView(context, attrs, defStyle) {

        private lateinit var onItemClick: (District) -> Unit
        private var selectDistrict: District? = null
        private var districtList = ArrayList<District>()

        private var lastSelectIndex = -1
        private var currentSelctedIndex = -1

        init {
            layoutManager = LinearLayoutManager(
                context,
                LinearLayoutManager.VERTICAL,
                false
            )
            // 直接使用匿名适配器
            adapter = object : RecyclerView.Adapter<HiViewHolder>() {
                override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HiViewHolder {
                    // 直接返回 HiViewHolder实例
                    return HiViewHolder(
                        LayoutInflater.from(context)
                            .inflate(R.layout.dialog_city_selector_list_item, parent, false)
                    )
                }

                override fun onBindViewHolder(holder: HiViewHolder, position: Int) {
                    val checkedTextView = holder.findViewById<CheckedTextView>(R.id.title)
                    val district = districtList[position]
                    checkedTextView?.text = district.districtName

                    holder.itemView.setOnClickListener {
                        selectDistrict = district
                        currentSelctedIndex = holder.adapterPosition
                        // 改变上次选中控件的状态
                        notifyItemChanged(lastSelectIndex)
                        // 改变这次被选中控件的状态
                        notifyItemChanged(position)
                    }

                    // 点击之后触发刷新,说明当前item 是本次选中项
                    if (currentSelctedIndex == position && currentSelctedIndex != lastSelectIndex) {
                        onItemClick(district)
                    }

                    // 点击之后以及首次进入时刷新 item
                    if (selectDistrict?.id == district.id) {
                        currentSelctedIndex = holder.adapterPosition
                        lastSelectIndex = holder.adapterPosition
                    }
                    // 如果当前选中的index 和当前的position 是一致的,则是选中状态
                    checkedTextView?.isChecked = currentSelctedIndex == position
                }

                override fun getItemCount(): Int = districtList.size

            }
        }

        /**
         * setData 带有个带参的接口回调
         */
        fun setData(select: District?, list: List<District>?, onItemClick: (District) -> Unit) {
            if (list.isNullOrEmpty()) return
            // 设置默认值为-1
            lastSelectIndex = -1
            currentSelctedIndex = -1
            this.onItemClick = onItemClick
            selectDistrict = select
            districtList.clear()
            districtList.addAll(list)
            // 由于recyclerview可能还没布局完成,这里使用 post进行notify
            post {
                adapter?.notifyDataSetChanged()
            }
        }
    }

}